package com.stenio.fancat.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stenio.fancat.domain.ActOperLog;
import com.stenio.fancat.domain.ActStatistics;
import com.stenio.fancat.domain.ActType;
import com.stenio.fancat.domain.Activity;
import com.stenio.fancat.domain.Brand;
import com.stenio.fancat.domain.User;
import com.stenio.fancat.domain.UserAccount;
import com.stenio.fancat.domain.UserAccountLog;
import com.stenio.fancat.domain.UserImage;
import com.stenio.fancat.domain.bo.ActivityBO;
import com.stenio.fancat.domain.bo.JoinActivityBO;
import com.stenio.fancat.domain.bo.PublishActivityBO;
import com.stenio.fancat.domain.bo.UserActivityBO;
import com.stenio.fancat.domain.bo.UserBO;
import com.stenio.fancat.form.UserForm;
import com.stenio.fancat.mapper.ActOperLogMapper;
import com.stenio.fancat.mapper.ActStatisticsMapper;
import com.stenio.fancat.mapper.ActTypeMapper;
import com.stenio.fancat.mapper.ActivityMapper;
import com.stenio.fancat.mapper.UserAccountLogMapper;
import com.stenio.fancat.mapper.UserAccountMapper;
import com.stenio.fancat.mapper.UserImageMapper;
import com.stenio.fancat.mapper.UserMapper;
import com.stenio.fancat.util.IOUtil;
import com.stenio.fancat.util.StringUtil;

/**
 * 用户模块服务实现类
 */
@Service
public class UserService extends ServiceImpl<UserMapper, User> {

	@Autowired
	private ActivityMapper activityMapper;
	@Autowired
	private ActOperLogMapper actOperLogMapper;
	@Autowired
	private ActTypeMapper actTypeMapper;
	@Autowired
	private ActStatisticsMapper actStatisticsMapper;
	@Autowired
	private UserAccountMapper userAccountMapper;
	@Autowired
	private UserAccountLogMapper userAccountLogMapper;
	@Autowired
	private UserImageMapper userImageMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private UserImageService userImageService;
	@Value("${userImagePrefix}")
	public String userImagePrefix;

	/**
	 * 通过用户ID或手机号获取用户以及账户信息，参与活动，收入，支出
	 * 
	 * @param user
	 *            用户实体类
	 * 
	 * @return UserBO对象
	 */
	public UserBO queryUserInfoByCondition(UserForm userForm) {

		if (null == userForm || (null == userForm.getUserId() && StringUtils.isBlank(userForm.getPhone()))) {
			throw new RuntimeException("参数不能为空");
		}
		User user = new User();
		try {
			BeanUtils.copyProperties(user, userForm);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("参数转换有误");
		}
		User userInfo = userMapper.selectOne(user);
		if (null == userInfo) {
			throw new RuntimeException("用户信息异常");
		}
		UserBO userBO = new UserBO();
		try {
			BeanUtils.copyProperties(userBO, userInfo);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("用户信息异常");
		}
		Integer userId = userInfo.getUserId();
		// 获取用户账户
		userBO.setSurplusCandy(queryUserAccount(userId).getSurplusCandy());
		// 获取收入
		Map<String, Object> map = actOperLogMapper.selectSUMByUid(userId);
		Integer income = 0;
		if (null != map && null != map.get(ActOperLog.REWARD))
			income = Integer.valueOf(map.get(ActOperLog.REWARD).toString());
		userBO.setIncome(income);
		// 获取支出
		Integer expenditure = activityMapper.selectExpenditureByUserId(userId);
		userBO.setExpenditure(null == expenditure ? 0 : expenditure);
		// 获取完成任务
		List<ActOperLog> ActOperLogList = actOperLogMapper
				.selectList(new EntityWrapper<ActOperLog>().eq(ActOperLog.USER_ID, userId).groupBy(ActOperLog.ACT_ID));
		userBO.setDoneActivity(null == ActOperLogList ? 0 : ActOperLogList.size());
		// 获取发布任务
		List<Activity> activityList = activityMapper
				.selectList(new EntityWrapper<Activity>().eq(ActOperLog.USER_ID, userId));
		userBO.setPublishActivity(null == activityList ? 0 : activityList.size());
		return userBO;
	}

	/**
	 * 获取用户发布活动时初始化数据
	 * 
	 * @param userId
	 *            发布人ID
	 */
	public UserActivityBO queryUserInfoByUserId(Integer userId) {

		if (null == userId) {
			throw new RuntimeException("参数不能为空");
		}

		// 获取用户所发布的品牌
		List<Activity> actList = activityMapper.selectList(new EntityWrapper<Activity>().eq(Activity.USER_ID, userId));
		List<Brand> brandList = new ArrayList<Brand>();
		if (null != actList && actList.size() > 0) {
			Set<Integer> brandIdSet = new HashSet<Integer>();
			for (Activity a : actList) {
				Integer branId = a.getBrandId();
				// 包含跳出执行下一条
				if (brandIdSet.contains(branId)) {
					continue;
				}
				Brand brand = new Brand();
				brand.setBrandId(branId);
				brand.setBrandName(a.getBrandName());
				brandIdSet.add(branId);
				brandList.add(brand);
			}
		}

		// 获取可用的活动类型
		List<ActType> actTypesList = actTypeMapper.selectList(new EntityWrapper<ActType>().eq(ActType.TYPE_STAT, 0));

		// 获取账户
		UserAccount account = queryUserAccount(userId);

		UserActivityBO uaBO = new UserActivityBO();
		uaBO.setBrands(brandList);
		uaBO.setPublishTypes(actTypesList);
		uaBO.setUserAccount(account);
		return uaBO;
	}

	/**
	 * 通过用户ID获取账户信息
	 * 
	 * @param userId
	 *            用户ID
	 * @return 账户信息
	 */
	public UserAccount queryUserAccount(Integer userId) {
		UserAccount entity = new UserAccount();
		entity.setUserId(userId);
		return userAccountMapper.selectOne(entity);
	}

	/**
	 * 用户参与的活动列表
	 * 
	 * @param userId
	 *            用户ID
	 * @return
	 */
	public Page<JoinActivityBO> queryUserJoinAct(UserForm userForm) {
		if (null == userForm || null == userForm.getUserId())
			throw new RuntimeException("参数不能为空");
		// 通过活动操作日志获取用户参与的活动
		Page<JoinActivityBO> page = new Page<JoinActivityBO>(userForm.getCurrentPageNo(), userForm.getPageSize());
		List<ActOperLog> actOperLogList = actOperLogMapper.selectByConditionPage(page, userForm.getUserId());
		List<JoinActivityBO> actBOList = new ArrayList<JoinActivityBO>();
		if (null != actOperLogList && actOperLogList.size() > 0) {
			for (ActOperLog actOperLog : actOperLogList) {
				JoinActivityBO joinActivityBO = new JoinActivityBO();
				joinActivityBO.setActionTime(actOperLog.getCreateTime());
				Integer actId = actOperLog.getActId();
				// 获取活动并设置返回结果
				Activity activity = activityMapper.selectById(actId);
				if (null == activity) {
					throw new RuntimeException("活动数据异常");
				}
				joinActivityBO.setActId(actId);
				joinActivityBO.setPublishTitle(activity.getPublishTitle());
				joinActivityBO.setBrandId(activity.getBrandId());
				joinActivityBO.setBrandName(activity.getBrandName());
				joinActivityBO.setActTypeId(activity.getActTypeId());
				joinActivityBO.setPublishType(activity.getPublishType());
				// 转发、点击的金额取活动的设置值
				joinActivityBO.setActionCandy(activity.getResendCandy());
				joinActivityBO.setTapCandy(activity.getTapCandy());
				joinActivityBO.setActivityCandy(activity.getResendCandy() + activity.getTapCandy());

				// 获取活动统计

				ActStatistics entity = new ActStatistics();
				entity.setActId(actId);
				ActStatistics actStatistics = actStatisticsMapper.selectOne(entity);
				if (null == actStatistics) {
					throw new RuntimeException("活动统计数据异常");
				}
				joinActivityBO.setTapNumber(actStatistics.getTapCount());
				actBOList.add(joinActivityBO);
			}
		}
		return page.setRecords(actBOList);
	}

	/**
	 * 用户发布的活动列表
	 * 
	 * @param userId
	 *            用户ID
	 * @return
	 */
	public Page<PublishActivityBO> queryUserPublishAct(UserForm userForm) {
		if (null == userForm || null == userForm.getUserId())
			throw new RuntimeException("参数不能为空");
		// 获取用户发起的活动列表
		Page<PublishActivityBO> page = new Page<PublishActivityBO>(userForm.getCurrentPageNo(), userForm.getPageSize());
		Activity activity = new Activity();
		activity.setUserId(userForm.getUserId());
		List<ActivityBO> activityBOList = activityMapper.selectByConditionPage(page, activity);
		// 组织返回结果列表
		List<PublishActivityBO> actBOList = new ArrayList<PublishActivityBO>();
		if (null != activityBOList && activityBOList.size() > 0) {
			for (ActivityBO activityBO : activityBOList) {
				PublishActivityBO paBO = new PublishActivityBO();
				paBO.setActId(activityBO.getActId());
				paBO.setActionCandy(activityBO.getResendCandy());
				paBO.setActionNumber(activityBO.getResendCount());
				paBO.setActivityCandy(activityBO.getTotleCandy() - activityBO.getSurplusCandy());
				paBO.setActTypeId(activityBO.getActTypeId());
				paBO.setBlAdress("");
				paBO.setBrandId(activityBO.getBrandId());
				paBO.setBrandName(activityBO.getBrandName());
				paBO.setPublishTime(activityBO.getBeginTime());
				paBO.setPublishTitle(activityBO.getPublishTitle());
				paBO.setPublishType(activityBO.getPublishType());
				paBO.setSurplusCandy(activityBO.getSurplusCandy());
				paBO.setTapCandy(activityBO.getTapCandy());
				paBO.setTapNumber(activityBO.getTapCount());
				paBO.setThumbs(activityBO.getThumbs());
				paBO.setTotalCandy(activityBO.getTotleCandy());
				actBOList.add(paBO);
			}
		}
		return page.setRecords(actBOList);
	}

	/**
	 * 增加减少用户账户余额
	 * 
	 * @param userId
	 *            用户ID
	 * @param amount
	 *            操作金额
	 * @param type
	 *            0增加，1减少，
	 */
	@Transactional
	public void saveUserAccount(Integer userId, Integer amount, int type) {
		// 获取账户
		UserAccount account = queryUserAccount(userId);
		Integer surplusCandy = account.getSurplusCandy();
		UserAccountLog record = new UserAccountLog();
		// 增加减少账户余额
		if (type == 0) {
			account.setSurplusCandy(surplusCandy + amount);
			record.setOperType(0);
		} else {
			// 判断余额不足
			if (amount > surplusCandy) {
				throw new RuntimeException("用户账户余额不足,剩余金额为:" + surplusCandy);
			}
			account.setSurplusCandy(surplusCandy - amount);
			record.setOperType(1);
		}
		// 组装日志表数据
		record.setAccountId(account.getId());
		record.setAfterCandy(account.getSurplusCandy());
		record.setBeforeCandy(surplusCandy);
		record.setCandy(amount);
		record.setUserId(userId);
		userAccountMapper.updateAllColumnById(account);
		userAccountLogMapper.insertSelective(record);
	}

	/**
	 * 更新用户信息
	 * 
	 * @param
	 */
	@Transactional
	public void saveUser(UserForm userForm) {
		// userId、phone参数不可同时为空
		if (null == userForm || (null == userForm.getUserId() && StringUtils.isBlank(userForm.getPhone()))) {
			throw new RuntimeException("参数不能为空");
		}
		Integer userId = userForm.getUserId();
		String phone = userForm.getPhone();
		String nikeName = userForm.getNikeName();
		String userName = userForm.getUserName();
		// 通过用户id、手机号查询是否存在此用户
		User userQuery = new User();
		if (StringUtils.isNotBlank(phone)) {
			if (!StringUtil.isMobile(phone))
				throw new RuntimeException("手机号格式有误");
			userQuery.setPhone(phone);
		}
		if (null != userId)
			userQuery.setUserId(userForm.getUserId());
		User userResult = userMapper.selectOne(userQuery);

		// 图片地址不为空需要保存到数据库中
		byte[] image = null;
		if (StringUtils.isNotBlank(userForm.getHeadPic())) {
			try {
				image = IOUtil.toByteArray(userForm.getHeadPic());
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException("图片格式或URL有误");
			}
		}

		if (null != userResult && null != userResult.getUserId()) {// 查询到用户执行更新操作
			userId = userResult.getUserId();
			if (StringUtils.isNotBlank(nikeName))
				userResult.setNikeName(nikeName);
			if (StringUtils.isNotBlank(userName))
				userResult.setUserName(userName);
			// 更新用户信息以及图片信息
			if (null != image) {
				// 查询用户头像
				UserImage userImage = userImageService.queryUserImageByCondition(userId, 0);
				if (null != userImage) {// 更新图片
					if (null != image) {
						userImage.setImage(image);
						userImageMapper.updateById(userImage);
					}
				} else {// 新增图片
					userImage = new UserImage();
					userImage.setUserId(userId);
					userImage.setImage(image);
					userImage.setImgType(0);
					userImageMapper.insertSelective(userImage);
					userResult.setHeadPic(userImagePrefix + userId);
				}
			}
			userMapper.updateById(userResult);
		} else {// 没查询到用户执行新增操作
			// 再次通过手机号查询，确保手机号没有被使用
			if (StringUtils.isBlank(phone)) {
				throw new RuntimeException("手机号不能为空");
			} else {
				User u = new User();
				u.setPhone(phone);
				User uResult = userMapper.selectOne(u);
				// 查出了用户信息说明传入的参数userId、phone不匹配
				if (null != uResult && null != uResult.getUserId())
					throw new RuntimeException("传入的参数不匹配");
			}
			User user = new User();
			if (StringUtils.isBlank(nikeName))
				user.setNikeName(phone);
			user.setNikeName(nikeName);
			user.setPhone(phone);
			if (StringUtils.isBlank(userName))
				user.setUserName(phone);
			user.setUserName(userName);
			// 保存用户信息
			userMapper.insertSelective(user);
			if (null != image) {
				// 保存用户图片信息
				UserImage userImage = new UserImage();
				userImage.setUserId(user.getUserId());
				userImage.setImage(image);
				userImage.setImgType(0);
				userImageMapper.insertSelective(userImage);
				// 写入图片地址
				user.setHeadPic(userImagePrefix + user.getUserId());
				userMapper.updateById(user);
			}
			// 保存用户账户信息
			UserAccount userAccount = new UserAccount();
			userAccount.setUserId(user.getUserId());
			userAccountMapper.insert(userAccount);
		}
	}

}
